// import * as THREE from './three.module.js';
// import { Line2 } from './Line2.js';
// import { LineMaterial } from './LineMaterial.js';
// import { LineGeometry } from './LineGeometry.js';
var __mapcenter__ = [116.582, 35.415];
mapboxgl.accessToken = 'pk.eyJ1IjoiaG91eGlleXUiLCJhIjoiY2pldjE5amU3NndzeDM5bzd5bm9ncDgycyJ9.j1F-Lgid3L5k2Abm8_xTeQ';
var mapboxgl_style = {
    "version": 8,
    "sprite": "mapbox://sprites/mapbox/dark-v10",
    "glyphs": "mapbox://fonts/mapbox/{fontstack}/{range}.pbf",
    "sources": {
        "raster-tiles": {
            "type": "raster",
            'tiles': [
                'http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
            ],
            "tileSize": 256
        }
    },
    "layers": [
        {
            "id": "simple-tiles",
            "type": "raster",
            "source": "raster-tiles",
            "minzoom": 0,
            "maxzoom": 18
        },

    ]
}
// var mapboxgl_style = 'mapbox://styles/mapbox/dark-v10';

var map = new mapboxgl.Map({
    container: 'map',
    style: mapboxgl_style,
    zoom: 9,
    center: __mapcenter__,
    pitch: 60,
    antialias: true // create the gl context with MSAA antialiasing, so custom layers are antialiased
});

$.ajaxSettings.async = false;
// configuration of the custom layer for a 3D model per the CustomLayerInterface
function initThree(_this, mapd) {
    _this.camera = new THREE.Camera();
    _this.scene = new THREE.Scene();
    const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
    directionalLight.position.set(0, -70, 100).normalize();
    _this.scene.add(directionalLight);

    var lights = [];
    lights[0] = new THREE.AmbientLight(0xffffff, 0.6, 0);

    _this.scene.add(lights[0]);

    _this.map = mapd;
}
var mbpt = lnglatToMector(__mapcenter__, 0);
var threescale = mbpt.meterInMercatorCoordinateUnits();
var customLayer = {
    id: '3d-model',
    type: 'custom',
    renderingMode: '3d',
    onAdd: function (mapd, gl) {
        initThree(this, mapd);
        //绘制乡镇发热人数柱图
        drawBars(this.scene);
        //绘制确诊地点覆盖图
        drawQZs();
        this.renderer = new THREE.WebGLRenderer({
            canvas: mapd.getCanvas(),
            antialias: true,
            alpha: true,
            context: gl,
        });
        this.renderer.autoClear = false;

        this.labelRenderer = new CSS2DRenderer();
        this.labelRenderer.setSize($('#map').width(), $('#map').height());
        this.labelRenderer.domElement.style.position = 'absolute';
        this.labelRenderer.domElement.style.top = 0;
        this.labelRenderer.domElement.style['pointer-events'] = 'none';
        document.body.appendChild(this.labelRenderer.domElement);
        this.labelRenderer.autoClear = false;

    },
    render: function (gl, matrix) {
        var m = new THREE.Matrix4().fromArray(matrix);
        var l = new THREE.Matrix4()
            .makeTranslation(
                mbpt.x,
                mbpt.y,
                mbpt.z
            )
            .scale(
                new THREE.Vector3(
                    threescale,
                    -threescale,
                    threescale
                )
            );
        this.camera.projectionMatrix = m.multiply(l);
        this.renderer.state.reset();
        this.renderer.render(this.scene, this.camera);

        this.labelRenderer.render(this.scene, this.camera);

        this.map.triggerRepaint();
    }
};

map.on('style.load', function () {
    var qzpts = getQZPTs();
    let demo = new CountUp('qzrs', qzpts.length, {
        duration: 5
    });
    demo.start();
    var kycrd = qzpts.reduce(function(zs,val){
        var t = JSON.parse(val.points);
        return zs + (t?t.length:0)
    },0);
    demo = new CountUp('kycrd', kycrd, {
        duration: 5
    });
    demo.start();

    var qzdata = createGEO(qzpts);
    var bufs = turf.buffer(turf.featureCollection(qzdata.features), 3, { units: 'kilometers' });
    //覆盖面图层
    map.addSource('qrft', {
        'type': 'geojson',
        'data': bufs
    });
    map.addLayer({
        'id': 'qrft',
        'type': 'fill',
        'source': 'qrft',
        'layout': {},
        'paint': {
            'fill-color': defaultcolor,
            'fill-opacity': 0.2
        }
    });
    map.addImage('pulsing-dot1', pulsingDot('255, 200, 200', '255, 100, 100', true), { pixelRatio: 2 });
    //闪烁点数据源
    map.addSource("qzpts", {
        type: "geojson",
        data: qzdata,// encodeURI(serverurl + "&filter=1=2"),
        clusterMaxZoom: 14, // Max zoom to cluster points on
        clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
    });
    //闪烁点图层
    map.addLayer(scatterlayer);

    map.addLayer(customLayer);
    map.on('mouseenter', 'qzpts', showInfo);
    map.on('mouseleave', 'qzpts', function () {
            // map.getCanvas().style.cursor = '';
            popup.remove();
    });

    addbjlayer();
});
var popup = new mapboxgl.Popup({
    closeButton: false,
    closeOnClick: true
});
function showInfo(e) {
    // if (!$('#showinfo').prop('checked')) return;
    // Change the cursor style as a UI indicator.
    map.getCanvas().style.cursor = 'pointer';
    selft = e.features[0];
    var coordinates = e.features[0].geometry.coordinates.slice();
    function formatinfo(props) {
        var info = "<div style='margin:5px'>";
        var shfld = {
            'addr': '地址'
        }
        for (prop in props) {
            if (shfld[prop]) {
                info += shfld[prop] + ":" + props[prop] + "<br>";
            }
        }
        info += "</div>";
        return info;
    }
    var description = formatinfo(e.features[0].properties);
    // $('.showtext')[0].innerHTML = description;
    // Ensure that if the map is zoomed out such that multiple
    // copies of the feature are visible, the popup appears
    // over the copy being pointed to.
    while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
        coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
    }

    // Populate the popup and set its coordinates
    // based on the feature found.
    popup.setLngLat(coordinates)
        .setHTML(description)
        .addTo(map);
    clickflag = false;
}
function createGEO(qzpts) {
    var fts = [];
    qzpts.forEach(function (ry) {
        var pts = JSON.parse(ry.points)
        if (pts == null) return;
        pts.forEach(function (pt) {
            fts.push({
                type: 'Feature',
                properties: {
                    ryid: ry.id,
                    name: ry.name,
                    addr: pt.addr,
                    qx: pt.qx
                },
                geometry: {
                    type: 'Point',
                    coordinates: [pt.lng, pt.lat]
                }
            })
        })
    })
    return {
        "type": "FeatureCollection",
        features: fts
    }
}
var defaultcolor = '#CC0000'
map.on('load', function () {

});
/**
  * @desc 经纬度转换成墨卡托投影
  * @param {array} 传入经纬度
  * @return array [x,y,z]
  */
function lnglatToMector(lnglat, height) {
    return mapboxgl.MercatorCoordinate.fromLngLat(
        lnglat,
        height
    );
}

function lnglatToLocal(lnglat, height) {
    var pt = lnglatToMector(lnglat, height);
    return {
        x: (pt.x - mbpt.x) / threescale,
        y: -(pt.y - mbpt.y) / threescale,
        z: height
    }
}
// buildingjson.features.forEach(ft => {
//     ft.properties.ftcolor = '#CCCCFF';
// })

var shines = [];

var colors = ['#FF6666', '#FFFF00', '#0066CC'];
function barDataToGeoJSON(datas) {
    var features = [];
    datas.forEach(function (feature) {
        features.push({
            type: 'Feature',
            properties: {
                name: feature.name,
                value: feature.value,
                code: feature.code
            },
            geometry: {
                type: 'Point',
                coordinates: [feature.geometry.x, feature.geometry.y]
            }
        });
    })
    return {
        "type": "FeatureCollection",
        features: features
    }
}
function getXZPTs() {
    var ret;
    $.getJSON('http://124.133.27.90:6080/arcgis/rest/services/jiningjp4/MapServer/6/query',
        {
            where: "1=1",
            f: 'pjson',
            outFields: 'np.DBO.T3708xiang_pt.name,np.DBO.T3708xiang_pt.areacode'
        }, function (res) {
            ret = res.features;
        });
    return ret;
}
var serveraddr = 'http://124.133.27.84:8080/main/';
function getQZPTs() {
    var ret;
    $.getJSON(serveraddr + 'getQZ',
        function (res) {
            ret = res;
        });
    return ret;
}
function getBarsData() {
    var ret;
    $.getJSON(serveraddr + 'getSummary',
        function (res) {
            ret = res;
        });
    return ret;
}

function getBarVal(barsData, code) {
    var ob = barsData.find(function (data) {
        return data.code == code
    });
    return ob ? ob.rs : 0;
}
function buildBars(scene, renderData) {
    var max = renderData.reduce(function (max, num) {
        if (num.value * 1 > max.value * 1)
            return num
        else
            return max
    }).value;

    const barwidth = 500;
    renderData.forEach(function (pt) {

        var height = pt.value * 20000.0 / max;//getBarHeight(barsData, max, pt.attributes['np.DBO.T3708xiang_pt.areacode']);
        var barXZGeo = new THREE.CylinderBufferGeometry(barwidth, barwidth, height, 32);
        barXZGeo.translate(0, height / 2, 0);
        barXZGeo.rotateX(Math.PI / 2)
        // var meshMaterial = new THREE.MeshPhongMaterial({ color: 0x156289, emissive: 0x072534, side: THREE.DoubleSide, flatShading: true });
        // var clr = "rgb("
        // + linerData(0, max, 0, 255, pt.value) + "," + linerData(0, max, 50, 250,  pt.value) + ","
        // + linerData(0, max, 255, 0,  pt.value)
        // + ")";
        var clr = "rgb("
            + linerData(0, max, 150, 250, pt.value) + "," + linerData(0, max, 150, 50, pt.value) + ","
            + linerData(0, max, 200, 50, pt.value)
            + ")";
        var barXZMaterial = new THREE.MeshStandardMaterial({ color: clr });

        var meshMaterial = new THREE.MeshPhongMaterial({
            color: clr,
        });

        var barXZMesh = new THREE.Mesh(barXZGeo, barXZMaterial);
        var { x, y, z } = lnglatToLocal([pt.geometry.x, pt.geometry.y], 0);
        barXZMesh.position.set(x, y, z);
        // add2DLabel(barXZMesh,pt,height);
        scene.add(barXZMesh)
    })
}
function add2DLabel(barXZMesh, pt, height) {
    var labelDiv = document.createElement('div');
    labelDiv.className = 'label';
    labelDiv.textContent = pt.name + ' 人数：' + pt.value;
    // earthDiv.style.marginTop = '-1em';
    labelDiv.style.color = 'white';
    labelDiv.style['font-size'] = '12px';

    var earthLabel = new CSS2DObject(labelDiv);
    earthLabel.position.set(0, 0, height);
    barXZMesh.add(earthLabel);
}
function getRenderData(xzpts, barsData) {
    var ret = [];
    xzpts.forEach(function (pt) {
        var val = getBarVal(barsData, pt.attributes['np.DBO.T3708xiang_pt.areacode']);
        if (val == 0) return;
        ret.push({
            name: pt.attributes['np.DBO.T3708xiang_pt.name'],
            code: pt.attributes['np.DBO.T3708xiang_pt.areacode'],
            value: val,
            geometry: pt.geometry
        })
    })
    return ret;
}
function drawBars(scene) {
    //获取乡镇点数据
    var xzpts = getXZPTs();
    var barsData = getBarsData();
    var sum = barsData.reduce(function(t,v){
        return t+v.rs
    },0 )
    let demo = new CountUp('frjz', sum, {
        duration: 5
    });
    demo.start();

    var renderData = getRenderData(xzpts, barsData);
    //构造几何
    buildBars(scene, renderData);
    //labellayer
    addLabelLayer(renderData);
}

function addLabelLayer(renderData) {
    //非聚合单位数据源
    map.addSource("pcdxpoints", {
        type: "geojson",
        data: barDataToGeoJSON(renderData),// encodeURI(serverurl + "&filter=1=2"),
        // cluster: true,
        clusterMaxZoom: 14, // Max zoom to cluster points on
        clusterRadius: 50 // Radius of each cluster when clustering points (defaults to 50)
    });
    //标注图层
    map.addLayer({
        id: "pcdxlabel",
        type: "symbol",
        source: "pcdxpoints",
        layout: {
            "text-field": "{name}{value}",
            "text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
            "text-size": 12,
            // visibility: 'none'
        },
        paint: {
            "text-color": 'white',
            "text-halo-color": "black",
            "text-halo-width": 1,
        }
    });
}
function drawQZs() {

}

//线性插值
function linerData(omin, omax, tmin, tmax, input) {
    return Math.floor(tmin + (input - omin) * (tmax - tmin) / (omax - omin));
}

//点图层
var scatterlayer = {
    id: "qzpts",
    type: "symbol",
    source: "qzpts",
    layout: {
        'icon-image': 'pulsing-dot1',
        'icon-allow-overlap': true,
        'icon-ignore-placement': true
    }
};

var size = 100;

// implementation of CustomLayerInterface to draw a pulsing dot icon on the map
// see https://docs.mapbox.com/mapbox-gl-js/api/#customlayerinterface for more info
function pulsingDot(rgb1, rgb2, shine) {
    return {
        width: size,
        height: size,
        data: new Uint8Array(size * size * 4),

        // get rendering context for the map canvas when layer is added to the map
        onAdd: function () {
            var canvas = document.createElement('canvas');
            canvas.width = this.width;
            canvas.height = this.height;
            this.context = canvas.getContext('2d');
        },

        // called once before every frame where the icon will be used
        render: function () {
            var duration = shine ? 1000 : 999999;
            var t = (performance.now() % duration) / duration;

            var radius = (size / 2) * 0.3;
            var outerRadius = shine ? ((size / 2) * 0.7 * t + radius) : 0;
            var context = this.context;

            // draw outer circle
            context.clearRect(0, 0, this.width, this.height);
            context.beginPath();
            context.arc(
                this.width / 2,
                this.height / 2,
                outerRadius,
                0,
                Math.PI * 2
            );
            context.lineWidth = 1;
            context.fillStyle = 'rgba(' + rgb1 + ',' + (1 - t) + ')';
            context.fill();

            // draw inner circle
            context.beginPath();
            context.arc(
                this.width / 2,
                this.height / 2,
                radius,
                0,
                Math.PI * 2
            );
            context.fillStyle = 'rgba(' + rgb2 + ', 1)';
            context.strokeStyle = 'white';
            // context.lineWidth = 2 + 4 * (1 - t);
            context.lineWidth = 1;

            context.fill();
            context.stroke();

            // update this image's data with data from the canvas
            this.data = context.getImageData(
                0,
                0,
                this.width,
                this.height
            ).data;

            // continuously repaint the map, resulting in the smooth animation of the dot
            map.triggerRepaint();

            // return `true` to let the map know that the image was updated
            return true;
        }
    };
}
var jiningbj = {
    "type": "FeatureCollection",
    features: []
};
var xiangjibj = {
    "type": "FeatureCollection",
    features: []
};var xianjibj = {
    "type": "FeatureCollection",
    features: []
};
function addbjlayer(){
        //县级边界图层
        map.addSource("xianjibj", {
            type: "geojson",
            data: jiningbj,
            // generateId:true
        });
        map.addLayer({
            'id': 'xianjibj',
            // 'type': 'fill',
            type: 'line',
            'source': 'xianjibj',
            'paint': {
                'line-color': 'red'
            },
        });
        map.addLayer({
            'id': 'xianjibjzj',
            'type': 'symbol',
            'source': 'xianjibj',
            layout: {
                "text-field": "{name}",
                // "text-field": "{id}",
                "text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
                "text-size": 14,
    
            },
            paint: {
                "text-color": 'white',
                "text-halo-color": "black",
                "text-halo-width": 1,
                // "text-halo-blur":2
            }
        });
        //乡级边界图层
        // map.addSource("xiangjibj", {
        //     type: "geojson",
        //     data: xiangjibj,
        // });
        // map.addLayer({
        //     'id': 'xiangjibj',
        //     type: 'line',
        //     'source': 'xiangjibj',
        //     'paint': {
        //         'line-color': 'green'
        //     },
        //     layout: {
        //         visibility: 'none'
        //     }
        // });
        // map.addLayer({
        //     'id': 'xiangjibjzj',
        //     'type': 'symbol',
        //     'source': 'xiangjibj',
        //     layout: {
        //         "text-field": "{name}",
        //         // "text-field": "{id}",
        //         "text-font": ["DIN Offc Pro Medium", "Arial Unicode MS Bold"],
        //         "text-size": 12,
        //         visibility: 'none'
        //     },
        //     paint: {
        //         "text-color": 'white'
        //     }
        // });
  
    
        loadBJ(xianjibj, 'xianjibj', '3708', '0');
        // loadBJ(xiangjibj, 'xiangjibj', __areacode__, '1');
    }
    function loadBJ(layer, source, area, level) {
        $.getJSON('http://124.133.27.90:6080/arcgis/rest/services/jiningbj/MapServer/' + level + '/query', {
            where: '1=1 and areacode like \'' + area + '%\'',
            outFields: 'OBJECTID,name,areacode',
            returnGeometry: true,
            f: 'pjson'
        }, function (res) {
            res.features.forEach(feature => {
                var coords = [];
                feature.geometry.rings.forEach(ring => {
                    coords.push([ring]);
                });
                layer.features.push({
                    type: 'Feature',
                    properties: feature.attributes,
                    geometry: {
                        type: 'MultiPolygon',
                        // coordinates:[feature.geometry.rings]
                        coordinates: coords
                    },
                    id: feature.attributes.OBJECTID
                });
            });
            map.getSource(source).setData(layer);
        });
    }